package demo.huodongbaoming.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.discovery.DiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 负载均衡测试控制器
 */
@RestController
@RequestMapping("/api/loadbalancer")
public class LoadBalancerTestController {

    @Autowired
    private LoadBalancerClient loadBalancerClient;

    @Autowired
    private DiscoveryClient discoveryClient;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 测试负载均衡 - 直接使用LoadBalancerClient选择服务实例
     * @param serviceId 服务ID
     * @return 选择的服务实例信息
     */
    @GetMapping("/choose/{serviceId}")
    public Map<String, Object> chooseService(@PathVariable String serviceId) {
        ServiceInstance instance = loadBalancerClient.choose(serviceId);
        
        Map<String, Object> result = new HashMap<>();
        if (instance == null) {
            result.put("error", "No instances available for " + serviceId);
            return result;
        }
        
        result.put("serviceId", instance.getServiceId());
        result.put("host", instance.getHost());
        result.put("port", instance.getPort());
        result.put("uri", instance.getUri().toString());
        result.put("metadata", instance.getMetadata());
        result.put("timestamp", System.currentTimeMillis());
        
        return result;
    }
    
    /**
     * 测试负载均衡 - 多次调用，展示负载均衡效果
     * @param serviceId 服务ID
     * @param count 调用次数
     * @return 多次选择的服务实例信息
     */
    @GetMapping("/test/{serviceId}/{count}")
    public Map<String, Object> testLoadBalancer(@PathVariable String serviceId, @PathVariable int count) {
        Map<String, Object> result = new HashMap<>();
        List<Map<String, Object>> instances = new java.util.ArrayList<>();
        
        for (int i = 0; i < count; i++) {
            ServiceInstance instance = loadBalancerClient.choose(serviceId);
            if (instance != null) {
                Map<String, Object> instanceInfo = new HashMap<>();
                instanceInfo.put("serviceId", instance.getServiceId());
                instanceInfo.put("host", instance.getHost());
                instanceInfo.put("port", instance.getPort());
                instanceInfo.put("callNumber", i + 1);
                instances.add(instanceInfo);
            }
        }
        
        // 统计各实例被调用的次数
        Map<String, Long> instanceCounts = instances.stream()
                .collect(Collectors.groupingBy(
                        m -> m.get("host") + ":" + m.get("port"), 
                        Collectors.counting()));
        
        result.put("service", serviceId);
        result.put("totalCalls", count);
        result.put("instanceCalls", instanceCounts);
        result.put("callDetails", instances);
        
        return result;
    }
    
    /**
     * 获取指定服务的所有实例
     * @param serviceId 服务ID
     * @return 服务实例列表
     */
    @GetMapping("/instances/{serviceId}")
    public List<Map<String, Object>> getServiceInstances(@PathVariable String serviceId) {
        List<ServiceInstance> instances = discoveryClient.getInstances(serviceId);
        return instances.stream().map(instance -> {
            Map<String, Object> instanceInfo = new HashMap<>();
            instanceInfo.put("serviceId", instance.getServiceId());
            instanceInfo.put("host", instance.getHost());
            instanceInfo.put("port", instance.getPort());
            instanceInfo.put("uri", instance.getUri().toString());
            instanceInfo.put("metadata", instance.getMetadata());
            return instanceInfo;
        }).collect(Collectors.toList());
    }
} 